package com.chenyun.gateway.dynamic.service;

import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

/**
 * RouteServiceImpl：
 * Description:
 *
 * @author: Lonni
 * @date: 2022/11/18 0018 10:55
 */
@Service
@Slf4j
@AllArgsConstructor
public class RouteServiceImpl implements RouteService, ApplicationEventPublisherAware {

    private final RouteDefinitionWriter routeDefinitionWriter;

    private ApplicationEventPublisher eventPublisher;

    /**
     * 添加路由
     *
     * @param routeDefinition
     * @return
     */
    @Override
    public Boolean addRoute(RouteDefinition routeDefinition) {
        log.info("新增路由配置项,内容:{}", JSON.toJSONString(routeDefinition));
        routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        // 发布应用程序更新事件
        this.eventPublisher.publishEvent(new RefreshRoutesEvent(this));
        return true;
    }

    /**
     * 很据路由id删除路由配置
     *
     * @param routeId
     * @return
     */
    @Override
    public Mono<ResponseEntity<Object>> deleteRoute(String routeId) {
        log.info("删除路由配置项,路由id:{}",routeId);
     return   this.routeDefinitionWriter.delete(Mono.just(routeId))
               //删除完成后执行
               .then(Mono.defer(()->{
                   return Mono.just(ResponseEntity.ok().build());
               }))
               //错误处理
              .onErrorResume((t)->{
                  return  t instanceof NotFoundException;
              },(r)->{
                  return  Mono.just(ResponseEntity.notFound().build());
              }) ;

    }

    /**
     * 更新路由配置
     *
     * @param routeDefinition
     * @return
     */
    @Override
    public Boolean updateRoute(RouteDefinition routeDefinition) {
        log.info("更新路由配置,内容:{}",JSON.toJSONString(routeDefinition));
        //先删除  在添加
        this.deleteRoute(routeDefinition.getId());
        log.info("先删除路由:{}配置",routeDefinition.getId());
        this.addRoute(routeDefinition);
        return true;
    }

    /**
     * 发布事件器
     * @param applicationEventPublisher event publisher to be used by this object
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.eventPublisher = applicationEventPublisher;
    }
}



